package com.javaex.book.utils;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.mysql.cj.jdbc.AbandonedConnectionCleanupThread;

/**
 * JDBC工具类。用于获取jdbc连接
 *
 * @author 黄星琦
 * @Date 2022年1月16日
 */
public class JdbcUtils {
	
	private static DruidDataSource dataSource;
	private static Logger logger = LoggerFactory.getLogger(JdbcUtils.class);
	private static ThreadLocal<Connection> conns = new ThreadLocal<>();
	
	static {
		Properties properties = new Properties(); 
		InputStream is = JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
		try { 
			properties.load(is);
			dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
		} catch (Exception e) {
			logger.error("数据库连接池加载失败", e);
		}
	}
 
	/**
	 * 从连接池获取数据库连接
	 * @return 数据库连接
	 * @throws SQLException 
	 */
	public static Connection getConnection() {
		Connection connection = conns.get();
		if (connection == null) {
			try {
				connection = dataSource.getConnection();
				conns.set(connection);
				connection.setAutoCommit(false);	// 设置为手动提交事务
			} catch (SQLException e) {
				throw new RuntimeException(e);
			}
		}
		return connection;
	}
	
	/**
	 * 提交事务，并关闭数据库连接
	 * @throws SQLException 
	 */
	public static void commitAndClose() {
		Connection connection = conns.get();
		if (connection != null) {
			try {
				connection.commit();
			} catch (Exception e) {
				throw new RuntimeException(e);
			} finally {
				try {
					connection.close();
				} catch (SQLException e) {
					throw new RuntimeException(e);
				}
			}
		}
		conns.remove();
	}
	
	/**
	 * 回滚事务，并关闭数据库连接
	 * @throws SQLException 
	 */
	public static void rollbackAndClose() {
		Connection connection = conns.get();
		if (connection != null) {
			try {
				try {
					connection.rollback();	// 回滚事务
				} catch (SQLException e) {
					throw new RuntimeException(e);
				}	
			} finally {
				try {
					connection.close();
				} catch (SQLException e) {
					throw new RuntimeException(e);
				}
			}
		}
		conns.remove();
	}
	
	/**
	 * 关闭数据源
	 */
	public static void closeDataSource() {
		dataSource.close();
		Enumeration<Driver> drivers = DriverManager.getDrivers();
		while (drivers.hasMoreElements()) {
            Driver driver = drivers.nextElement();
            try {
                DriverManager.deregisterDriver(driver);
            } catch (SQLException e) {
                logger.error("注销数据库驱动失败", e);
            }
        }
	    //手动停止名为[mysql-cj-abandoned-connection-cleanup]的线程
	    AbandonedConnectionCleanupThread.uncheckedShutdown();
	}
}
